package main

import (
	"bytes"
	"database/sql"
	_ "embed"
	"encoding/json"
	"fmt"
	"io"
	mr "math/rand"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/fatih/color"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	_ "github.com/mattn/go-sqlite3"
	"github.com/qtgolang/SunnyNet/SunnyNet"
	"github.com/qtgolang/SunnyNet/public"
	"github.com/sirupsen/logrus"

	"wx_channel/pkg/argv"
	"wx_channel/pkg/certificate"
	"wx_channel/pkg/proxy"
	"wx_channel/pkg/util"
)

type ChannelProfile struct {
	Title string `json:"title"`
}
type FrontendTip struct {
	Msg string `json:"msg"`
}
type QueueData struct {
	Op     string      `json:"op"`
	Data   interface{} `json:"data"`
	Rid    string      `json:"rid"`
	Status string      `json:"status"`
}

type User struct {
	UserID      string  `json:"user_id"`
	UserName    string  `json:"user_name" binding:"required"`
	PhoneNumber string  `json:"phone_number"`
	Price       float64 `json:"price" binding:"required"`
}

//go:embed certs/SunnyRoot.cer
var cert_data []byte

//go:embed lib/FileSaver.min.js
var file_saver_js []byte

//go:embed lib/jszip.min.js
var zip_js []byte

//go:embed inject/main.js
var main_js []byte

var request_queue = make([]*QueueData, 0)
var response_queue = make([]*QueueData, 0)
var requestQueueMutex sync.Mutex
var responseQueueMutex sync.Mutex

// JWT 密钥 生产环境请用 env， 不要用硬编码
var jwtKey = []byte("7b9a3f8c2d1e4f5a8c9b7d6f3e2a1b4c")

// endpoints
var endpoints = map[string]float64{
	"/search": 0.0500,
}

// 定义 JWT 声明
type Claims struct {
	UserID   string `json:"user_id"`
	UserName string `json:"user_name"`
	jwt.StandardClaims
}

// 检查用户名是否已存在
func userNameExists(userName string) bool {
	var count int
	err := db.QueryRow("SELECT COUNT(*) FROM users WHERE user_name = ?", userName).Scan(&count)
	if err != nil {
		log.Errorf("查询用户表失败: %v", err)
		return false
	}
	return count > 0
}

// 删除队列指定数据
func RemoveFromSliceByRid(slice []*QueueData, rid string) []*QueueData {
	for i, v := range slice {
		if v.Rid == rid {
			return append(slice[:i], slice[i+1:]...)
		}
	}
	return slice
}

// 安全地从 request_queue 中移除元素
func safeRemoveFromRequestQueue(rid string) {
	requestQueueMutex.Lock()
	defer requestQueueMutex.Unlock()
	request_queue = RemoveFromSliceByRid(request_queue, rid)
}

// 安全地从 response_queue 中移除元素
func safeRemoveFromResponseQueue(rid string) {
	responseQueueMutex.Lock()
	defer responseQueueMutex.Unlock()
	response_queue = RemoveFromSliceByRid(response_queue, rid)
}

// 安全地向 request_queue 添加元素
func safeAppendToRequestQueue(item *QueueData) {
	requestQueueMutex.Lock()
	defer requestQueueMutex.Unlock()
	request_queue = append(request_queue, item)
}

// 安全地向 response_queue 添加元素
func safeAppendToResponseQueue(item *QueueData) {
	responseQueueMutex.Lock()
	defer responseQueueMutex.Unlock()
	response_queue = append(response_queue, item)
}

// 安全地查找 response_queue 中的元素
func safeFindInResponseQueue(rid string) *QueueData {
	responseQueueMutex.Lock()
	defer responseQueueMutex.Unlock()
	for _, item := range response_queue {
		if item.Rid == rid {
			return item
		}
	}
	return nil
}

// 生成随机字符串
func generateRandomString(length int) string {
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, length)
	for i := range b {
		b[i] = letters[mr.Intn(len(letters))]
	}
	return string(b)
}

// 生成随机的查询参数
func generateRandomQueryParams() string {
	randomKey := generateRandomString(5)
	randomValue := generateRandomString(5)
	randomKey2 := generateRandomString(5)
	randomValue2 := generateRandomString(5)
	return "?" + randomKey + "=" + randomValue + "&" + randomKey2 + "=" + randomValue2
}

var Sunny = SunnyNet.NewSunny()
var version = generateRandomString(8) // 生成一个8位的随机字符串作为版本号
var v = generateRandomQueryParams()   // 生成随机的查询参数
var port = 2023
var log = logrus.New()
var db *sql.DB

// 初始化随机数生成器
func init() {
	// 创建所有目录
	os.MkdirAll("inject", os.ModeDir)
	os.MkdirAll("data", os.ModeDir)
	os.MkdirAll("temp", os.ModeDir)
	os.MkdirAll("lib", os.ModeDir)

	mr.Seed(time.Now().UnixNano())
	// Log as JSON instead of the default ASCII formatter.
	// log.Formatter = &logrus.JSONFormatter{
	// 	PrettyPrint: true,
	// }

	// 调试模式，删掉重新开始
	// file, _ := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	// log.SetOutput(file)

	var err error
	db, err = sql.Open("sqlite3", "./data/data.db")
	if err != nil {
		log.Fatal(err)
	}

	// 配置连接池
	db.SetMaxOpenConns(10)                 // 最大打开连接数
	db.SetMaxIdleConns(5)                  // 最大空闲连接数
	db.SetConnMaxLifetime(5 * time.Minute) // 连接的最大生命周期

	// 检查数据库是否可用
	err = db.Ping()
	if err != nil {
		log.Fatalf("无法连接到数据库: %v", err)
	}

	createUserTableSQL := `
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        user_id TEXT UNIQUE NOT NULL,
        user_name TEXT NOT NULL,
        phone_number TEXT NOT NULL,
		price DECIMAL(10, 4) NOT NULL DEFAULT 0.0000
    );
    `
	_, err = db.Exec(createUserTableSQL)
	if err != nil {
		log.Fatalf("无法创建用户表: %v", err)
	}

	createEndpointCostsTableSQL := `
    CREATE TABLE IF NOT EXISTS user_endpoint_costs (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
		user_id TEXT NOT NULL,
        endpoint TEXT UNIQUE NOT NULL,
		cost DECIMAL(10, 4) NOT NULL DEFAULT 0.0000
    );
    `
	_, err = db.Exec(createEndpointCostsTableSQL)
	if err != nil {
		log.Fatalf("无法创建请求成本表: %v", err)
	}
}

func updateUserPrice(endpoint, userId string) error {
	sql := `
		UPDATE users
		SET price = users.price - (
			SELECT cost
			FROM user_endpoint_costs
			WHERE user_endpoint_costs.user_id = users.user_id AND user_endpoint_costs.endpoint = ?
		)
		WHERE users.user_id = ?
	`
	_, err := db.Exec(sql, endpoint, userId)
	if err != nil {
		log.Errorf("更新用户价格时发生错误，%v", err)
		return err
	}
	return nil
}

func print_usage() {
	log.Infof("Usage: wx_video_download [OPTION...]\n")
	log.Infof("Download WeChat video.\n\n")
	log.Infof("      --help                 display this help and exit\n")
	log.Infof("  -v, --version              output version information and exit\n")
	log.Infof("  -p, --port                 set proxy server network port\n")
	log.Infof("  -d, --dev                  set proxy server network device\n")
	os.Exit(0)
}

func main() {
	log.Infof("wx_video_download v%s\n", version, v)

	os_env := runtime.GOOS
	args := argv.ArgsToMap(os.Args) // 分解参数列表为Map
	if _, ok := args["help"]; ok {
		print_usage()
	} // 存在help则输出帮助信息并退出主程序
	if v, ok := args["v"]; ok { // 存在v则输出版本信息并退出主程序
		log.Infof("v%s %.0s\n", version, v)
		os.Exit(0)
	}
	if v, ok := args["version"]; ok { // 存在version则输出版本信息并退出主程序
		log.Infof("v%s %.0s\n", version, v)
		os.Exit(0)
	}
	if v, ok := args["jwt"]; ok {
		jwtKey = []byte(v)
	}
	// 设置参数默认值
	args["dev"] = argv.ArgsValue(args, "", "d", "dev")
	args["port"] = argv.ArgsValue(args, "", "p", "port")
	iport, errstr := strconv.Atoi(args["port"])
	if errstr != nil {
		args["port"] = strconv.Itoa(port) // 用户自定义值解析失败则使用默认端口
	} else {
		port = iport
	}

	delete(args, "p") // 删除冗余的参数p
	delete(args, "d") // 删除冗余的参数d

	signalChan := make(chan os.Signal, 1)
	// Notify the signal channel on SIGINT (Ctrl+C) and SIGTERM
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		sig := <-signalChan
		log.Infof("\n正在关闭服务...%v\n\n", sig)
		if os_env == "darwin" {
			proxy.DisableProxyInMacOS(proxy.ProxySettings{
				Device:   args["dev"],
				Hostname: "127.0.0.1",
				Port:     args["port"],
			})
		}
		os.Exit(0)
	}()

	go func() {
		serverAddr := "0.0.0.0:8080"
		common := gin.Default()

		// 需要鉴权的路由组
		auth := common.Group("/")
		auth.Use(authMiddleware())
		{
			auth.GET("/search", handleSearch)
			auth.GET("/getUser", handleGetUser)
		}

		common.POST("/addUser", handleAddUser)
		if err := common.Run(serverAddr); err != nil {
			log.Infof("服务器启动失败:", err)
		}
	}()
	log.Infof("\nv" + version)
	log.Infof("\n问题反馈 https://github.com/ltaoo/wx_channels_download/issues\n")
	existing, err1 := certificate.CheckCertificate("SunnyNet")
	if err1 != nil {
		log.Infof("\nERROR %v\v", err1.Error())
		log.Infof("按 Ctrl+C 退出...\n")
		select {}
	}
	if !existing {
		log.Infof("\n\n正在安装证书...\n")
		err := certificate.InstallCertificate(cert_data)
		time.Sleep(3 * time.Second)
		if err != nil {
			log.Infof("\nERROR %v\n", err.Error())
			log.Infof("按 Ctrl+C 退出...\n")
			select {}
		}
	}
	Sunny.SetPort(port)
	Sunny.SetGoCallback(HttpCallback, nil, nil, nil)
	err := Sunny.Start().Error
	if err != nil {
		log.Infof("\nERROR %v\n", err.Error())
		log.Infof("按 Ctrl+C 退出...\n")
		select {}
	}
	proxy_server := fmt.Sprintf("127.0.0.1:%v", port)
	client := &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyURL(&url.URL{
				Scheme: "http",
				Host:   proxy_server,
			}),
		},
	}
	_, err3 := client.Get("https://sunny.io/")
	if err3 == nil {
		if os_env == "windows" {
			ok := Sunny.StartProcess()
			if !ok {
				log.Infof("\nERROR 启动进程代理失败\n")
				log.Infof("按 Ctrl+C 退出...\n")
				select {}
			}
			Sunny.ProcessAddName("WeChatAppEx.exe")
		}
		if os_env == "darwin" {
			err := proxy.EnableProxyInMacOS(proxy.ProxySettings{
				Device:   args["dev"],
				Hostname: "127.0.0.1",
				Port:     args["port"],
			})
			if err != nil {
				log.Infof("\nERROR 设置代理失败 %v\n", err.Error())
				log.Infof("按 Ctrl+C 退出...\n")
				select {}
			}
		}
		color.Green(fmt.Sprintf("\n\n服务已正确启动，请打开需要下载的视频号页面进行下载"))
	} else {
		log.Infof(fmt.Sprintf("\n\n您还未安装证书，请在浏览器打开 http://%v 并根据说明安装证书\n在安装完成后重新启动此程序即可\n", proxy_server))
	}
	log.Infof("\n\n服务正在运行，按 Ctrl+C 退出...")
	select {}
}

func handleAddUser(c *gin.Context) {
	var userReq User
	if err := c.ShouldBindJSON(&userReq); err != nil {
		log.Errorf("绑定 JSON 请求体失败: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 如果有用户名了，请求失败
	if userNameExists(userReq.UserName) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "用户名已存在"})
		return
	}

	log.Infof("成功绑定 JSON 请求体: %v", userReq)

	userReq.UserID = uuid.NewString()
	log.Infof("生成的用户 ID: %s", userReq.UserID)

	// 生成 JWT 令牌
	expirationTime := time.Now().Add(24 * time.Hour)
	claims := &Claims{
		UserID: userReq.UserID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(),
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString(jwtKey)
	if err != nil {
		log.Errorf("生成 JWT 令牌失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法生成令牌"})
		return
	}

	log.Infof("成功生成 JWT 令牌: %s", tokenString)

	tx, err := db.Begin()
	if err != nil {
		log.Errorf("开始事务失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法开始事务"})
		return
	}
	defer tx.Rollback()

	// 将用户信息存储到数据库
	insertUserSQL := `
		INSERT INTO users (user_id, user_name, phone_number, price)
		VALUES (?, ?, ?, ?)
	`
	_, err = tx.Exec(insertUserSQL, userReq.UserID, userReq.UserName, userReq.PhoneNumber, userReq.Price)
	if err != nil {
		log.Errorf("插入用户信息到数据库失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法插入用户信息到数据库"})
		return
	}

	log.Infof("成功插入用户信息到数据库: %v", userReq)

	// 生成 user_endpoint_costs 表数据
	for endpoint, price := range endpoints {
		insertEndpointCostSQL := `
			INSERT INTO user_endpoint_costs (user_id, endpoint, cost)
			VALUES (?, ?, ?)
		`
		_, err := tx.Exec(insertEndpointCostSQL, userReq.UserID, endpoint, price)
		if err != nil {
			log.Errorf("无法插入用户端点价格到数据库: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{"error": "无法插入用户端点价格到数据库"})
			return
		}
	}

	if err := tx.Commit(); err != nil {
		log.Errorf("提交事务失败: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法提交事务"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"token": tokenString,
		"user":  userReq,
	})
}

func handleGetUser(c *gin.Context) {
	userId := c.Query("user_id")
	if userId == "" {
		log.Error("user_id不能为空")
		c.JSON(http.StatusBadRequest, gin.H{"error": "user_id不能为空"})
		return
	}

	var user User
	err := db.QueryRow("SELECT user_id, user_name, phone_number, price FROM users WHERE user_id = ?", userId).Scan(&user.UserID, &user.UserName, &user.PhoneNumber, &user.Price)
	if err != nil {
		log.Error("无法获取用户信息:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法获取用户信息"})
		return
	}
	c.JSON(http.StatusOK, user)
}

func handleSearch(c *gin.Context) {
	log.Infof("handleSearch %s", c.Request.URL.Path)

	// 获取 userID 和 userName
	userID, err := c.Get("userID")
	if !err {
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": "未登录",
		})
		return
	}

	// 推送请求数据
	rid := uuid.NewString()
	data := map[string]interface{}{
		"title": c.Query("title"),
		"name":  c.Query("name"),
	}
	item := &QueueData{Data: data, Rid: rid, Status: "pending", Op: "/search"}
	safeAppendToRequestQueue(item)

	log.Infof("Push request data: %v, userId: %v", item, userID)

	// 循环等待响应数据，3分钟超时
	timeout := time.After(3 * time.Minute)
	for {
		select {
		case <-c.Request.Context().Done():
			log.Infof("取消了操作")
			safeRemoveFromResponseQueue(rid)
			c.JSON(http.StatusBadRequest, gin.H{"error": "请求已取消"})
			return
		case <-timeout:
			log.Infof("超时，没有收到响应")
			safeRemoveFromResponseQueue(rid)
			c.JSON(http.StatusRequestTimeout, gin.H{"error": "请求超时"})
			return
		default:
			// 查询 response_queue 中有没有存在 对应的 rid
			item := safeFindInResponseQueue(rid)
			if item != nil && item.Status == "done" {
				// 找到对应的响应数据，返回给客户端
				c.JSON(http.StatusOK, gin.H{
					"data": item.Data,
				})
				safeRemoveFromResponseQueue(rid)

				// 减少当前用户的费用
				log.Infof("用户 %s 的费用减少 %d", userID.(string), endpoints[item.Op])
				updateUserPrice(item.Op, userID.(string))
				return
			}
		}
	}
}

func authMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 白名单路径
		whiteList := []string{
			// "/search",
			"/addUser",
		}

		// 检查请求路径是否在白名单中
		for _, path := range whiteList {
			if c.Request.URL.Path == path {
				c.Next()
				return
			}
		}

		// 获取请求头中的 Authorization 字段
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "未提供 token"})
			c.Abort()
			return
		}

		// 提取 token
		tokenString := strings.Replace(authHeader, "Bearer ", "", 1)
		if tokenString == "" {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "无效的 token"})
			c.Abort()
			return
		}

		token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
			return jwtKey, nil
		})

		if err != nil {
			if ve, ok := err.(*jwt.ValidationError); ok {
				switch ve.Errors {
				case jwt.ValidationErrorExpired:
					c.JSON(http.StatusUnauthorized, gin.H{"error": "Token expired"})
					c.Abort()
					return
				default:
					c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
					c.Abort()
					return
				}
			} else {
				c.JSON(http.StatusUnauthorized, gin.H{"error": "Failed to parse token"})
				c.Abort()
				return
			}
		}

		if !token.Valid {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
			c.Abort()
			return
		}

		claims, ok := token.Claims.(*Claims)
		if !ok {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"})
			c.Abort()
			return
		}

		log.Infof("Token parsed successfully: %v", claims)

		// 使用解析后的 token 信息
		userID := claims.UserID
		userName := claims.UserName

		log.Infof("User ID: %s, User Name: %s", userID, userName)

		// 继续处理请求...
		c.Set("userID", userID)
		c.Set("userName", userName)
		c.Next()
	}
}
func HttpCallback(Conn *SunnyNet.HttpConn) {
	host := Conn.Request.URL.Hostname()
	path := Conn.Request.URL.Path
	// log.Infof("HttpCallback: %s %s", host, path)

	if Conn.Type == public.HttpSendRequest {
		// Conn.Request.Header.Set("Cache-Control", "no-cache")
		Conn.Request.Header.Del("Accept-Encoding")
		if util.Includes(path, "jszip") {
			headers := http.Header{}
			headers.Set("Content-Type", "application/javascript")
			headers.Set("__debug", "local_file")
			Conn.StopRequest(200, zip_js, headers)
			return
		}
		if util.Includes(path, "FileSaver.min") {
			headers := http.Header{}
			headers.Set("Content-Type", "application/javascript")
			headers.Set("__debug", "local_file")
			Conn.StopRequest(200, file_saver_js, headers)
			return
		}
		if path == "/__wx_channels_api/profile" {
			var data ChannelProfile
			body, _ := io.ReadAll(Conn.Request.Body)
			_ = Conn.Request.Body.Close()
			err := json.Unmarshal(body, &data)
			if err != nil {
				log.Infof(err.Error())
			}
			log.Infof("\n打开了视频\n%s\n", data.Title)
			headers := http.Header{}
			headers.Set("Content-Type", "application/json")
			headers.Set("__debug", "fake_resp")
			Conn.StopRequest(200, "{}", headers)
			return
		}
		if path == "/__wx_channels_api/report" {
			var data QueueData
			body, err := io.ReadAll(Conn.Request.Body)
			log.Infof("请求体: %s", string(body))
			if err != nil {
				log.Errorf("读取请求体失败: %v", err)
				Conn.StopRequest(200, "{}", nil)
				return
			}
			_ = Conn.Request.Body.Close()

			err = json.Unmarshal(body, &data)
			if err != nil {
				log.Errorf("解析请求体失败: %v", err)
				Conn.StopRequest(200, "", nil)
				return
			}

			// 发送数据
			if data.Op == "START_REQUEST" {
				if len(request_queue) > 0 {
					queue := request_queue[0]
					Conn.Request.Header.Set("X-RID", queue.Rid)
					safeRemoveFromRequestQueue(queue.Rid)
					queue.Status = "pending"
					safeAppendToResponseQueue(queue)
					log.Infof("请求体 data.Url: %s", queue.Rid)
				}
				Conn.Request.Header.Set("Content-Type", "application/json")
				return
			}

			// 拦截请求的数据
			if data.Op == "SEND_RESPONSE" {
				responseQueueMutex.Lock()
				defer responseQueueMutex.Unlock()
				// 将拦截的数据推送到 response_queue，并终止当前请求
				for _, item := range response_queue {
					if item.Rid == data.Rid {
						item.Status = "done"
						item.Data = data.Data
						log.Infof("更新 response_queue 中的 item: %v", item)
						break
					}
				}
				log.Infof("将 QueueData 添加到 response_queue %v", response_queue)
				return
			}

			return
		}
		if path == "/__wx_channels_api/tip" {
			var data FrontendTip
			body, _ := io.ReadAll(Conn.Request.Body)
			_ = Conn.Request.Body.Close()
			err := json.Unmarshal(body, &data)
			if err != nil {
				log.Infof(err.Error())
			}
			log.Infof("[FRONTEND]%s\n", data.Msg)
			headers := http.Header{}
			headers.Set("Content-Type", "application/json")
			headers.Set("__debug", "fake_resp")
			Conn.StopRequest(200, "{}", headers)
			return
		}
	}
	if Conn.Type == public.HttpResponseOK {
		content_type := strings.ToLower(Conn.Response.Header.Get("content-type"))

		if Conn.Response.Body != nil {
			Body, _ := io.ReadAll(Conn.Response.Body)
			_ = Conn.Response.Body.Close()

			// log.Infof("[FRONTEND]: %s\n", string(Body))

			// 根据 content-type 写入不同的文件
			switch {
			case strings.Contains(content_type, "text/html"):
				os.WriteFile("temp/html_response.html", Body, 0644)
			case strings.Contains(content_type, "application/javascript"):
				os.WriteFile("temp/js_response.js", Body, 0644)
			case strings.Contains(content_type, "application/json"):
				os.WriteFile("temp/json_response.json", Body, 0644)
			default:
				os.WriteFile("temp/other_response.txt", Body, 0644)
			}

			if path == "/__wx_channels_api/report" {
				Rid := Conn.Request.Header.Get("X-RID")
				log.Infof("接收到请求 %v", string(Body))

				if Rid == "" {
					Conn.StopRequest(200, "", nil)
					return
				}

				log.Infof("接收到 X-RID: %s", Rid)

				// 查找匹配的 QueueData
				var queue *QueueData
				for _, item := range response_queue {
					if item.Rid == Rid {
						queue = item
						break
					}
				}

				if queue == nil {
					log.Infof("未找到匹配的 QueueData，X-RID: %s", Rid)
					Conn.StopRequest(200, "", nil)
					return
				}

				// 将 QueueData 序列化为 JSON
				data, err := json.Marshal(queue)
				if err != nil {
					log.Errorf("编码数据失败: %v", err)
					return
				}

				log.Infof("发送数据: %v", string(data))

				// 设置响应头和响应体
				Conn.Response.Header.Set("Content-Type", "application/json")
				Conn.Response.Header.Set("__debug", "fake_resp")
				Conn.Response.Body = io.NopCloser(bytes.NewBuffer(data))
				Conn.Response.StatusCode = 200
				return
			}

			if content_type == "text/html; charset=utf-8" {
				// log.Infof("\n\n检测到页面打开")
				// log.Infof(path)
				html := string(Body)
				os.WriteFile("inject/old_index.html", []byte(html), 0644)
				script_reg1 := regexp.MustCompile(`src="([^"]{1,})\.js"`)
				html = script_reg1.ReplaceAllString(html, `src="$1.js`+v+`"`)
				script_reg2 := regexp.MustCompile(`href="([^"]{1,})\.js"`)
				html = script_reg2.ReplaceAllString(html, `href="$1.js`+v+`"`)
				Conn.Response.Header.Set("__debug", "append_script")
				script2 := ""
				// script2 := `<script src="https://debug.funzm.com/target.js"></script>`
				// 				script2 := `<script
				//       crossorigin="anonymous"
				//       src="https://pagespy.jikejishu.com/page-spy/index.min.js"
				//     ></script>
				//     <script
				//       crossorigin="anonymous"
				//       src="https://pagespy.jikejishu.com/plugin/data-harbor/index.min.js"
				//     ></script>
				//     <script
				//       crossorigin="anonymous"
				//       src="https://pagespy.jikejishu.com/plugin/rrweb/index.min.js"
				//     ></script>
				//     <!-- 使用第二步：实例化 PageSpy -->
				//     <script>
				//       window.$harbor = new DataHarborPlugin();
				//       window.$rrweb = new RRWebPlugin();
				//       [window.$harbor, window.$rrweb].forEach((p) => {
				//         PageSpy.registerPlugin(p);
				//       });

				//       // 实例化的参数都是可选的
				//       window.$pageSpy = new PageSpy({
				//         api: "pagespy.jikejishu.com",
				//         clientOrigin: "https://pagespy.jikejishu.com",
				//         project: "React 演示",
				//         autoRender: true,
				//         title: "PageSpy 🤝 React",
				//       });
				//       // 之后即可使用 PageSpy，前往 https://pagespy.jikejishu.com 体验
				//     </script>`

				log.Infof("2. 检测到页面打开 %s", path)
				if host == "channels.weixin.qq.com" && (path == "/web/pages/feed" || path == "/web/pages/home") {
					// Conn.Response.Header.Add("wx-channel-video-download", "1")
					script := fmt.Sprintf(`<script>%s</script>`, main_js)
					html = strings.Replace(html, "<head>", "<head>\n"+script+script2, 1)
					log.Infof("1. 视频详情页 html 注入 js 成功")
					os.WriteFile("inject/new_index.html", []byte(html), 0644)
					Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(html)))
					return
				}
				Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(html)))
				return
			}
			if content_type == "application/javascript" {
				content := string(Body)
				dep_reg := regexp.MustCompile(`"js/([^"]{1,})\.js"`)
				from_reg := regexp.MustCompile(`from {0,1}"([^"]{1,})\.js"`)
				lazy_import_reg := regexp.MustCompile(`import\("([^"]{1,})\.js"\)`)
				import_reg := regexp.MustCompile(`import {0,1}"([^"]{1,})\.js"`)
				content = from_reg.ReplaceAllString(content, `from"$1.js`+v+`"`)
				content = dep_reg.ReplaceAllString(content, `"js/$1.js`+v+`"`)
				content = lazy_import_reg.ReplaceAllString(content, `import("$1.js`+v+`")`)
				content = import_reg.ReplaceAllString(content, `import"$1.js`+v+`"`)
				Conn.Response.Header.Set("__debug", "replace_script")

				if util.Includes(path, "/t/wx_fed/finder/web/web-finder/res/js/index.publish") {
					regexp1 := regexp.MustCompile(`this.sourceBuffer.appendBuffer\(h\),`)
					replaceStr1 := `(() => {
if (window.__wx_channels_store__) {
window.__wx_channels_store__.buffers.push(h);
}
})(),this.sourceBuffer.appendBuffer(h),`
					if regexp1.MatchString(content) {
						log.Infof("2. 视频播放 js 修改成功")
					}
					content = regexp1.ReplaceAllString(content, replaceStr1)
					regexp2 := regexp.MustCompile(`if\(f.cmd===re.MAIN_THREAD_CMD.AUTO_CUT`)
					replaceStr2 := `if(f.cmd==="CUT"){
	if (window.__wx_channels_store__) {
	console.log("CUT", f, __wx_channels_store__.profile.key);
	window.__wx_channels_store__.keys[__wx_channels_store__.profile.key]=f.decryptor_array;
	}
}
if(f.cmd===re.MAIN_THREAD_CMD.AUTO_CUT`
					content = regexp2.ReplaceAllString(content, replaceStr2)
					Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(content)))
					return
				}
				if util.Includes(path, "/t/wx_fed/finder/web/web-finder/res/js/virtual_svg-icons-register") {
					log.Infof("修改注入内容")
					regexp1 := regexp.MustCompile(`async finderGetCommentDetail\((\w+)\)\{return(.*?)\}async`)
					replaceStr1 := `async finderGetCommentDetail($1) {
					var feedResult = await$2;
					var data_object = feedResult.data.object;
					if (!data_object.objectDesc) {
						return feedResult;
					}
					var media = data_object.objectDesc.media[0];
					var profile = media.mediaType !== 4 ? {
						type: "picture",
						id: data_object.id,
						title: data_object.objectDesc.description,
						files: data_object.objectDesc.media,
						spec: [],
						contact: data_object.contact
					} : {
						type: "media",
						duration: media.spec[0].durationMs,
						spec: media.spec,
						title: data_object.objectDesc.description,
						coverUrl: media.coverUrl,
						url: media.url+media.urlToken,
						size: media.fileSize,
						key: media.decodeKey,
						id: data_object.id,
						nonce_id: data_object.objectNonceId,
						nickname: data_object.nickname,
						createtime: data_object.createtime,
						fileFormat: media.spec.map(o => o.fileFormat),
						contact: data_object.contact
					};
					fetch("/__wx_channels_api/profile", {
						method: "POST",
						headers: {
							"Content-Type": "application/json"
						},
						body: JSON.stringify(profile)
					});
					if (window.__wx_channels_store__) {
					__wx_channels_store__.profile = profile;
					window.__wx_channels_store__.profiles.push(profile);
					}
					return feedResult;
				}async`
					if regexp1.MatchString(content) {
						log.Infof("3. 视频详情页 js 修改成功")
					}
					content = regexp1.ReplaceAllString(content, replaceStr1)
					regex2 := regexp.MustCompile(`r.default={dialog`)
					replaceStr2 := `r.default=window.window.__wx_channels_tip__={dialog`
					content = regex2.ReplaceAllString(content, replaceStr2)
					regex3 := regexp.MustCompile(`const u=this.storage.getSession`)
					replaceStr3 := `return;const u = this.storage.getSession`
					content = regex3.ReplaceAllString(content, replaceStr3)
					regex4 := regexp.MustCompile(`return this.storage.getSession`)
					replaceStr4 := `return null;return this.storage.getSession`
					content = regex4.ReplaceAllString(content, replaceStr4)
					regex5 := regexp.MustCompile(`this.updateDetail\(o\)`)
					replaceStr5 := `(() => {
					if (Object.keys(o).length===0){
					return;
					}
					var data_object = o;
					var media = data_object.objectDesc.media[0];
					var profile = media.mediaType !== 4 ? {
						type: "picture",
						id: data_object.id,
						title: data_object.objectDesc.description,
						files: data_object.objectDesc.media,
						spec: [],
						contact: data_object.contact
					} : {
						type: "media",
						duration: media.spec[0].durationMs,
						spec: media.spec,
						title: data_object.objectDesc.description,
						url: media.url+media.urlToken,
						size: media.fileSize,
						key: media.decodeKey,
						id: data_object.id,
						nonce_id: data_object.objectNonceId,
						nickname: data_object.nickname,
						createtime: data_object.createtime,
						fileFormat: media.spec.map(o => o.fileFormat),
						contact: data_object.contact
					};
					if (window.__wx_channels_store__) {
window.__wx_channels_store__.profiles.push(profile);
					}
					})(),this.updateDetail(o)`
					content = regex5.ReplaceAllString(content, replaceStr5)
					// 读取 inject/ws_api.js 的内容，并追加到 content 钟
					f, _ := os.Open("inject/ws_api.js")
					// 转成字符串
					defer f.Close()
					if ctx, err := io.ReadAll(f); err == nil {
						content = content + "\n" + string(ctx)
					}
					log.Infof("4. 视频详情页 js 追加成功")
					os.WriteFile("inject/new_ws_api.js", []byte(content), 0644)
					Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(content)))
					return
				}
				if util.Includes(path, "/t/wx_fed/finder/web/web-finder/res/js/FeedDetail.publish") {
					regex := regexp.MustCompile(`,"投诉"\)]`)
					replaceStr := `,"投诉"),...(() => {
					if (window.__wx_channels_store__ && window.__wx_channels_store__.profile) {
						return window.__wx_channels_store__.profile.spec.map((sp) => {
							return p("div",{class:"context-item",role:"button",onClick:() => __wx_channels_handle_click_download__(sp)},sp.fileFormat);
						});
					}
					})(),p("div",{class:"context-item",role:"button",onClick:()=>__wx_channels_handle_click_download__()},"原始视频"),p("div",{class:"context-item",role:"button",onClick:__wx_channels_download_cur__},"当前视频"),p("div",{class:"context-item",role:"button",onClick:()=>__wx_channels_handle_download_cover()},"下载封面"),p("div",{class:"context-item",role:"button",onClick:__wx_channels_handle_copy__},"复制链接")]`
					content = regex.ReplaceAllString(content, replaceStr)
					Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(content)))
					return
				}
				if util.Includes(path, "worker_release") {
					regex := regexp.MustCompile(`fmp4Index:p.fmp4Index`)
					replaceStr := `decryptor_array:p.decryptor_array,fmp4Index:p.fmp4Index`
					content = regex.ReplaceAllString(content, replaceStr)
					Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(content)))
					return
				}
				if util.Includes(path, "/t/wx_fed/finder/web/web-finder/res/js/worker-client") {
					log.Infof("5. worker-client js 追加成功")
					regexp1 := regexp.MustCompile(`window.xweb.worker.port.onmessage=u=>{`)
					// 拦截消息，替换为
					target1 := `window.xweb.worker.port.onmessage=u=>{ fetch("/__wx_channels_api/report", { body: JSON.stringify(u) });`
					content = regexp1.ReplaceAllString(content, target1)
					Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(content)))
					os.WriteFile("inject/new_worker-client.js", []byte(content), 0644)
					return
				}
				Conn.Response.Body = io.NopCloser(bytes.NewBuffer([]byte(content)))
				return
			}
			Conn.Response.Body = io.NopCloser(bytes.NewBuffer(Body))
		}
	}
	if Conn.Type == public.HttpRequestFail {
		//请求错误
		// Body := []byte("Hello Sunny Response")
		// Conn.Response = &http.Response{
		// 	Body: io.NopCloser(bytes.NewBuffer(Body)),
		// }
	}
}
